/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package wisp.game;

import java.util.*;
import java.util.Vector;
import wisp.dataObjects.*;
//import java.util.Iterator;

/**
 *
 * @author Shelley Chuateco Co
 */
public class Actions 
{
    private Random randomizer = new Random(System.currentTimeMillis());
    private Vector<String> messages = new Vector();
    private Vector<String> messageLog = new Vector();
    private String action = null;
    private double atkr = 0;
    private double defr = 0;
    private String ar = null;
    private String dr = null;
    private boolean doAtk = true;
    private int battleId = 0;
    
    public Actions() {}
    
    public boolean getSuccessACC (double successChance)
    {
        return ((successChance/100)<= randomizer.nextDouble());
    }
    
    public boolean getSuccessCrit (double successChance)
    {
        return ((successChance/100) >= randomizer.nextDouble());
    }
    
    public double getRandom(double min, double max) {
        return (max-min * randomizer.nextDouble()) + min;
    }
    
    public double attackAct(Statistics attacker, Statistics defender) {
        return attacker.getARate() - defender.getDRate();
    }
    
    public double critDamage(Statistics attacker, Statistics defender) {
        return (attacker.getCritRate() - (defender.getDef() / 5));
    }
    
    public double getMIN(int d)
    {
        return (d * 0.85);
    }
    
    public double computeDamage (WispCharacter attacker, Statistics statsAT, Statistics statsD, WispCharacter defender, String type, boolean accuracy)
    {
        double damage = 0.0;
        boolean isCrit = false, isAccrt = false;
       // isAccrt = this.getSuccessACC(attackAct(statsAT, statsD));
         isAccrt = accuracy;
        
        //System.out.println("4====================================ATTACKER : " + attacker.getCharactername());
        if (isAccrt)
        {
            double rand = 0.0;
            int hp = defender.getCHP();
            isCrit = this.getSuccessCrit(critDamage(statsAT, statsD));
            
            if (type.equals("atk"))
            {
                rand = this.getRandom(getMIN(statsAT.getAtk()), statsAT.getAtk());
                
                if (isCrit)
                    damage = Math.floor(rand  * 2);
                else
                    damage = Math.floor(rand - statsD.getDef());
                
                this.setDamage(attacker.getCharactername(), damage);
                
            }
            else if (type.equals("matk"))
            {
                rand = this.getRandom(getMIN(statsAT.getMAtk()), statsAT.getMAtk());
                
                if (isCrit)
                    damage = Math.floor(rand  * 2);
                else
                    damage = Math.floor(rand - (statsD.getRes() / 2));
                this.setDamage(attacker.getCharactername(), damage);
            }
            
            Double d = new Double(damage);
            defender.setCHP(hp - d.intValue());
            defender.editCharInfo(defender.getCharactername(), "currentHP", "", 0.0, defender.getCHP());
            if (!(this.getAction() == null))
            {//mana 
                //System.out.print(attacker.getCharactername() + " attacked " + defender.getCharactername() + " and dealt "+d.toString()+" "+this.getAction());
                this.getMessages().add(attacker.getCharactername() + " attacked " + defender.getCharactername() + " and dealt "+d.toString()+" "+this.getAction());
                this.setAction(null);
            }
            else
            {
                //System.out.print(attacker.getCharactername() + " attacked " + defender.getCharactername() + " and dealt "+d.toString()+" attack.");
                this.getMessages().add(attacker.getCharactername() + " attacked " + defender.getCharactername() + " and dealt "+d.toString()+" attack.");
            }
            if (isCrit)
            {   
                System.out.print(" critical hit!");
                this.getMessages().add(" CRITICAL HIT!!!");
            }
        }
        else 
        {
            //System.out.println(attacker.getCharactername() + " missed " + defender.getCharactername() + ".");
            //this.getMessages().add(attacker.getCharactername() + " missed " + defender.getCharactername() + ".");
        }
        return damage;
    }
    
    public double computeDamageC (WispCharacter attacker, Statistics statsAT, Statistics statsD, Monster defender, String type, boolean accuracy)
    {
        double damage = 0.0;
        boolean isCrit = false, isAccrt = false;
      //  isAccrt = this.getSuccessACC(attackAct(statsAT, statsD));
        isAccrt = accuracy;
        //System.out.println("4====================================ATTACKER : " + attacker.getCharactername());
        if (isAccrt)
        {
            double rand = 0.0;
            int hp = defender.getCHP();
            isCrit = this.getSuccessCrit(critDamage(statsAT, statsD));
            
            if (type.equals("atk"))
            {
                rand = this.getRandom(getMIN(statsAT.getAtk()), statsAT.getAtk());
                
                if (isCrit)
                    damage = Math.floor(rand  * 2);
                else
                    damage = Math.floor(rand - statsD.getDef());
                
               // this.setDamage(attacker.getCharactername(), damage);
            }
            else if (type.equals("matk"))
            {
                rand = this.getRandom(getMIN(statsAT.getMAtk()), statsAT.getMAtk());
                
                if (isCrit)
                    damage = Math.floor(rand  * 2);
                else
                    damage = Math.floor(rand - (statsD.getRes() / 2));
                
               // this.setDamage(attacker.getCharactername(), damage);
            }
            
            Double d = new Double(damage);
            defender.setCHP(hp - d.intValue());
        //    defender.editHP(defender.getId(),defender.getCHP());
            if (!(this.getAction() == null))
            {//mana 
                //System.out.print(attacker.getCharactername() + " attacked " + defender.getMName() + " and dealt "+d.toString()+" "+this.getAction());
                this.getMessages().add(attacker.getCharactername() + " attacked " + defender.getMName() + " and dealt "+d.toString()+" "+this.getAction());
                this.setAction(null);
            }
            else
            {
              //  System.out.print(attacker.getCharactername() + " attacked " + defender.getMName() + " and dealt "+d.toString()+" attack.");
                this.getMessages().add(attacker.getCharactername() + " attacked " + defender.getMName() + " and dealt "+d.toString()+" attack.");
            }
            if (isCrit)
            {   
                System.out.print(" critical hit!");
                this.getMessages().add(" CRITICAL HIT!!!");
            }
        }
        else 
        {
            //System.out.println(attacker.getCharactername() + " missed " + defender.getMName() + ".");
            this.getMessages().add(attacker.getCharactername() + " missed " + defender.getMName() + ".");
        }
        return damage;
    }
    
    public double computeDamageM (Monster attacker, Statistics statsAT, Statistics statsD, WispCharacter defender, boolean accuracy)
    {
        double damage = 0.0;
        boolean isCrit = false, isAccrt = false;
      //  isAccrt = this.getSuccessACC(attackAct(statsAT, statsD));
        isAccrt = accuracy;
       // System.out.println("4====================================ATTACKER : " + attacker.getMName());
        if (isAccrt)
        {
            double rand = 0.0;
            int hp = defender.getCHP();
            isCrit = this.getSuccessCrit(critDamage(statsAT, statsD));
            
            rand = this.getRandom(getMIN(statsAT.getAtk()), statsAT.getAtk());
                
            if (isCrit)
                damage = Math.floor(rand  * 2);
            else
                damage = Math.floor(rand - statsD.getDef());
            
           // this.setDamage(this.getAr(), damage);
            
            Double d = new Double(damage);
            defender.setCHP(hp - d.intValue());
          //  defender.editCharInfo(defender.getCharactername(), "currentHP", "", 0.0, defender.getCHP());
            
            if (!(this.getAction() == null))
            {//mana 
            //    System.out.print(attacker.getMName() + " attacked " + defender.getCharactername() + " and dealt "+d.toString()+" "+this.getAction());
                this.getMessages().add(attacker.getMName() + " attacked " + defender.getCharactername() + " and dealt "+d.toString()+" "+this.getAction());
                this.setAction(null);
            }
            else
            {
          //      System.out.print(attacker.getMName() + " attacked " + defender.getCharactername() + " and dealt "+d.toString()+" attack.");
                this.getMessages().add(attacker.getMName() + " attacked " + defender.getCharactername() + " and dealt "+d.toString()+" attack.");
            }
            if (isCrit)
            {   
                System.out.print(" critical hit!");
              //  this.getMessages().add(" CRITICAL HIT!!!");
            }
        }
        else 
        {
         //   System.out.println(attacker.getMName() + " missed " + defender.getCharactername() + ".");
            this.getMessages().add(attacker.getMName() + " missed " + defender.getCharactername() + ".");
        }
        return damage;
    }
    public int getNumAttacks(Statistics s) {
        return (int) Math.floor(s.getSpd() * 3);    // 3 secs
    }
    
    public void setDoAtk(boolean doAtk) {
        this.doAtk = doAtk;
    }
    
    public Statistics roundStat (int n, WispCharacter at, Statistics wcs)
    {
        String cname = at.getCharactername();
        boolean heal = false;
        int hl=0;
        
        ActionSlots as = new ActionSlots();
        SkillType st = null;
        Item itm = null;
        
        //temporary statistics
        Statistics stt = new Statistics();
        
        //computations class
        StatsCompPVP p = new StatsCompPVP();
        
        //equipment stats
        Statistics eqp = new Statistics();
        eqp = p.getEQPBonus(wcs);
        
        //bless stats
        Statistics bls = new Statistics();
        bls = p.getBlessBonus(at);
        
        this.setDoAtk(true);
        
        if (as.isHere(n, cname))
        {
            if (as.getActionName().equals(""))
                this.setDoAtk(false);
            
            else 
            {
                if (as.getType().equals("skill") && !as.getActionName().contains("IDLE"))
                {
                    st = new SkillType();
                    String skl = as.getActionName();
                    st.viewSkill(skl);

                    this.setAction(null);

                    if (st.getMpreq() <= at.getCMP())
                    {
                        at.editCharInfo(at.getCharactername(), "currentMP", "", 0, at.getCMP()-st.getMpreq());
                        at.viewChar(at.getCharactername());
                        this.setAction(" with "+skl);

                        if (as.getActionName().contains("Heal"))
                        {
                            hl = p.heal(st.getCurrentHP(), st.getSkillLevel(), at.getLevel(), wcs);
                            System.out.println("[heal] : "+hl);
                            heal = true;                             
                        }
                        if (st.getAtkType() == 0)//if buff
                        {
                            this.setDoAtk(false);
                            System.out.print(at.getCharactername()+" used "+st.getSkillName()+" with "+hl+".");
                            if (as.getActionName().contains("Heal"))
                            {
                                this.getMessages().add(at.getCharactername() + " used "+st.getSkillName()+ " and obtained additional " +hl+ " hp");
                                this.getMessageLog().add(at.getCharactername() + " used "+st.getSkillName()+ " and obtained additional " +hl+ " hp");
                            }
                            else
                            {
                                this.getMessages().add(at.getCharactername() + " used "+st.getSkillName()+".");
                                this.getMessageLog().add(at.getCharactername() + " used "+st.getSkillName()+".");
                            }
                        }
                    }
                    else
                    {
                        this.getMessages().add("Not enough MP to use "+skl);
                        this.getMessageLog().add("Not enough MP to use "+skl);
                        st = null;
                    }
                }
                else if (as.getType().equals("item"))
                {
                    Knapsack k = new Knapsack();
                    itm = new Item();

                    this.setDoAtk(false);

                    k.viewItem(as.getActionName(), cname);
                    itm.viewItem(as.getActionName());

                    if (itm.getItemType().startsWith("CON") && k.getQuantity() > 0)
                    {
                        this.setAction(" and used "+itm.getItemName());
                        k.editKnapsack(k.getCName(), itm.getItemName(), k.getSNum(), (k.getQuantity()-1), k.getWeight(), k.getItype(), k.getIsEquiped());

                        if (k.getQuantity() < 1)
                            k.editKnapsack(k.getCName(), "", k.getSNum(), 0, 0, "", 0);
                    }
                    else
                    {
                        this.getMessages().add("There is no "+k.getIName()+" left.");
                        this.getMessageLog().add("There is no "+k.getIName()+" left.");
                        itm = null;
                    }
                }
                
                
                stt.setStr(p.compSTR(cname, itm, st, wcs) + eqp.getStr() + bls.getStr());
                stt.setDex(p.compDEX(cname, itm, st, wcs) + eqp.getDex() + bls.getDex());
                stt.setCInt(p.compINT(cname, itm, st, wcs) + eqp.getCInt() + bls.getCInt());
                stt.setVit(p.compVIT(cname, itm, st, wcs) + eqp.getVit() + bls.getVit());
                stt.setSpr(p.compSPR(cname, itm, st, wcs) + eqp.getSpr() + bls.getSpr());

                stt.setCritRate(p.compCRIT(cname, itm, st, wcs) + eqp.getCritRate() + bls.getCritRate());
                stt.setBRate(p.compBlock(cname, itm, st, wcs) + eqp.getBRate() + bls.getBRate());
                stt.setARate(p.compACC(cname, itm, st, wcs) + eqp.getARate() + bls.getARate());
                stt.setDRate(p.compDodge(cname, itm, st, wcs) + eqp.getDRate() + bls.getDRate());

                stt.setAtk(p.compATK(cname, itm, st, wcs) + eqp.getAtk() + bls.getAtk());
                stt.setMAtk(p.compMATK(cname, itm, st, wcs) + eqp.getMAtk() + bls.getMAtk());

                stt.setRes(p.compRES(cname, itm, st, wcs) + eqp.getRes() + bls.getRes());
                stt.setDef(p.compDEF(cname, itm, st, wcs) + eqp.getDef() + bls.getDef());

                stt.setSpd(p.compSPD(cname, itm, st, wcs) + eqp.getSpd() + bls.getSpd());
                stt.setMobility(p.compMOB(cname, itm, st) + eqp.getMobility() + bls.getMobility());

                stt.setHpGR(p.compHPR(cname, itm, st, wcs) + bls.getHpGR());
                stt.setMpGR(p.compMPR(cname, itm, st, wcs) + bls.getMpGR());
                stt.setCharacterName(wcs.getCharacterName());
                stt.setStatType(1);

                at.editCharInfo(cname, "maxHP", "", 0, p.compMaxHP(cname, itm, st, at));
                at.editCharInfo(cname, "maxMP", "", 0, p.compMaxMP(cname, itm, st, at));

                int hp = 0;
                int mp = p.compCurMP(cname, itm, st, at);
                if (mp > at.getMMP())
                    mp = at.getMMP();
                at.editCharInfo(cname, "currentMP", "", 0, mp);
                
                if (heal)
                    hp = hl + at.getCHP();
                else
                    hp = p.compCurHP(cname, itm, st, at);
                
                if (hp > at.getMHP())
                    hp = at.getMHP();

                at.editCharInfo(cname, "currentHP", "", 0, hp);
            }//else
        }// if isHERE
        else
            this.setDoAtk(false);
        
        return stt;
    }
    

   
    public Statistics monsRoundStat (int n, Monster at, Statistics wcs)
    {
        Skill s = new Skill ();
        Statistics stt = new Statistics();
        StatsCompPVP p = new StatsCompPVP();
        String cname = at.getMName();
        
        System.out.println("2====================================ATTACKER : "+cname);
        
        this.setAction(cname+" attack");

        stt.setStr(p.compSTR(cname, null, null, wcs));
        stt.setDex(p.compDEX(cname, null, null, wcs));
        stt.setCInt(p.compINT(cname, null, null, wcs));
        stt.setVit(p.compVIT(cname, null, null, wcs));
        stt.setSpr(p.compSPR(cname, null, null, wcs));

        stt.setCritRate(p.compCRIT(cname, null, null, wcs));
        stt.setBRate(p.compBlock(cname, null, null, wcs));
        stt.setARate(p.compACC(cname, null, null, wcs));
        stt.setDRate(p.compDodge(cname, null, null, wcs));

        stt.setAtk(p.compATK(cname, null, null, wcs));
        stt.setMAtk(p.compMATK(cname, null, null, wcs));

        stt.setRes(p.compRES(cname, null, null, wcs));
        stt.setDef(p.compDEF(cname, null, null, wcs));

        stt.setSpd(p.compSPD(cname, null, null, wcs));
        stt.setMobility(p.compMOB(cname, null, null));

        stt.setHpGR(p.compHPR(cname, null, null, wcs));
        stt.setMpGR(p.compMPR(cname, null, null, wcs));
       
        return stt;
    }
    
    
    
    public void setDamage(String c, double dmg)
    {
    	try
    	{
        if (c.equals(this.getAr()))
            this.setAtkr(this.getAtkr()+dmg);
        else if (c.equals(this.getDr()))
            this.setDefr(this.getDefr()+dmg);
    	}
    	catch (NullPointerException nullp)
    	{
    		System.out.println ("value of c " + c);
    		System.out.println ("value of this " + this);
    	}
    }
    
  
    
    public int compEXP(double dmg)
    {
        return (int) Math.floor(dmg * 0.4);
    }
    
    public int compMNY(double exp)
    {
        return (int) Math.floor(exp * 0.6);
    }
    
     public Vector<String> getMessages() {
        return messages;
    }

    public String getAction() {
        return action;
    }

    public void setAction(String action) {
        this.action = action;
    }

   

    public String getAr() {
        return ar;
    }

    public void setAr(String ar) {
        this.ar = ar;
    }

    public String getDr() {
        return dr;
    }

    public void setDr(String dr) {
        this.dr = dr;
    }

    public double getAtkr() {
        return atkr;
    }

    public void setAtkr(double atkr) {
        this.atkr = atkr;
    }

    public double getDefr() {
        return defr;
    }

    public void setDefr(double defr) {
        this.defr = defr;
    }
    
    public void attackActionM (Monster attacker, Statistics statsAT, Statistics statsD, WispCharacter defender, WispCharacter wc)
    {
        String atype = "atk";
        
        System.out.println("ATK:"+wc.getCharactername()+" VERSUS "+"DEF:"+defender.getCharactername()+" "+statsAT.getCharacterName()+".");
        this.getMessages().add("ATTACKER:"+wc.getCharactername()+" with "+attacker.getMName()+" ---VERSUS--- DEFENDER:"+defender.getCharactername()+".");
        this.getMessageLog().add("ATTACKER:"+wc.getCharactername()+" with "+attacker.getMName()+" ---VERSUS--- DEFENDER:"+defender.getCharactername()+".");
        
        this.setAr(wc.getCharactername());
        this.setDr(defender.getCharactername());
        
        Feed ud = new Feed();
        
        Knapsack kn = new Knapsack();
        Vector<Knapsack> knVec = kn.viewEquip(defender.getCharactername());
        Iterator knIt = knVec.iterator();
        
        while (knIt.hasNext())
        {
            Knapsack itm = (Knapsack)knIt.next();
            if (itm.getSNum() == 1 && itm.getItype().equals("WPN-STAVES"))
                atype = "matk";
        }
        
        Statistics adStatsAt = new Statistics();
        for (int i = 0; i<24 && attacker.getCHP() > 0 && defender.getCHP() > 0; i++)
        {
            if(attacker.getCHP() < 1)
            {
                attacker.setCHP(0);
                attacker.editHP(attacker.getId(), 0);
                break;
            }
            else if (defender.getCHP() < 1)
            {
                defender.setCHP(0);
                defender.editCharInfo(defender.getCharactername(), "currentHP", "", 0, 0);
                break;
            }
            
            if (i%2 == 0)
            {
                System.out.println("about to attack............."+statsAT.getCharacterName());
                this.attackRoundMonsAttack(attacker, statsAT, statsD, defender);
            }
            else
            {
                adStatsAt = roundStat(((i/2)%4)+1, defender, statsD);
                System.out.println("about to attack............."+adStatsAt.getCharacterName());
                if (this.isDoAtk() == true)
                    this.attackRoundCharAttack(defender, adStatsAt, statsAT, attacker, atype);
            }
            
            defender.viewChar(defender.getCharactername());
            this.setAction(null);
        }
        
        wc.viewChar(this.getAr());
        defender.viewChar(this.getDr());
        
        this.getMessages().add("");
        //this.getMessageLog().add("");
        if (attacker.getCHP() <= 0)
        {
            attacker.editHP(attacker.getId(), 0);
            System.out.println(attacker.getMName() + " died.");
            this.getMessages().add(attacker.getMName() + " died.");
            this.getMessageLog().add(attacker.getMName() + " died.");
            this.getMessages().add("BATTLE WINNER IS: "+defender.getCharactername()+"!");
            this.getMessageLog().add("BATTLE WINNER IS: "+defender.getCharactername()+"!");
        }
        if (defender.getCHP() <= 0)
        {
            defender.editCharInfo(defender.getCharactername(), "currentHP", "", 0.0, 0);
            defender.editCharInfo(defender.getCharactername(), "status", "Dead", 0.0, 0);
            System.out.println(defender.getCharactername() + " died.");
            this.getMessages().add(defender.getCharactername() + " died.");
            this.getMessageLog().add(defender.getCharactername() + " died.");
            this.getMessages().add("BATTLE WINNER IS: "+attacker.getMName()+"!");
            this.getMessageLog().add("BATTLE WINNER IS: "+attacker.getMName()+"!");
        }
        
        int exp = this.compEXP(this.getAtkr());
        if (exp < 1)
            exp = 1;
        int money = this.compMNY(exp);
        
        if (money < 1)
            money = 0;
        
        System.out.println(this.getAr() + " gained "+ exp +" EXP.");
        System.out.println(this.getAr() + " gained "+ money +" money.");
        this.getMessages().add(this.getAr() + " gained "+ exp +" EXP.");
        this.getMessages().add(this.getAr() + " gained "+ money +" money.");
        
        this.getMessageLog().add(this.getAr() + " gained "+ exp +" EXP.");
        this.getMessageLog().add(this.getAr() + " gained "+ money +" money.");
                
        wc.editCharInfo(wc.getCharactername(), "experiencePt", "", 0, (wc.getEPoint()+exp));
        wc.editCharInfo(wc.getCharactername(), "pera", "", 0, (wc.getCMoney()+this.compMNY(exp)));
        CharLevel l = new CharLevel();
        l.viewExp((wc.getLevel()+1));
        
        if (l.getExpPt() < (wc.getEPoint()+exp))
        {
            this.getMessages().add(wc.getCharactername()+" has Levelled Up to "+  (wc.getLevel()+1));
            
            wc.editCharInfo(wc.getCharactername(), "cLevel", "", 0, (wc.getLevel()+1));
            wc.editCharInfo (wc.getCharactername(), "sCountLeft", "", 0, (wc.getSCountLeft()+1));
            
            Statistics wcs = new Statistics();
            wcs.viewStat(wc.getCharactername());
            
            this.doLevel(wcs, wc, wc.getLevel());
            
            Comrade com = new Comrade();
            Vector<Comrade> vec = com.viewCComrades(wc.getCharactername());
            
            ud = new Feed();
            ud.setCharInv(wc.getCharactername());
            ud.setCharacterName(wc.getCharactername());
            ud.setDateUpdated(CurrentDT.now());
            ud.setDescription(" have Levelled Up to "+  (wc.getLevel()+1));
            ud.setBattleId(0);            
            ud.addFeed(ud);
            
            if (!vec.isEmpty())
            {
                ud.setDescription(" has Levelled Up to "+  (wc.getLevel()+1));
                Iterator it = vec.iterator();
                Comrade friend = null;
                while(it.hasNext())
                {
                    friend = (Comrade)it.next();
                    ud.setCharacterName(friend.getFriendName());
                    ud.addFeed(ud);
                }
            }
        }
        
        exp = this.compEXP(this.getDefr());
        if (exp < 1)
            exp = 1;
        money = this.compMNY(exp);
        
        if (money < 1)
            money = 0;
        
        System.out.println(this.getDr() + " gained "+ exp +" EXP.");
        System.out.println(this.getDr() + " gained "+ money +" money.");
        this.getMessageLog().add(this.getDr()+ " gained "+ exp +" EXP.");
        this.getMessageLog().add(this.getDr() + " gained "+ money +" money.");
        
        defender.editCharInfo(defender.getCharactername(), "experiencePt", "", 0, (defender.getEPoint()+exp));
        defender.editCharInfo(defender.getCharactername(), "pera", "", 0, (defender.getCMoney()+money));
        l.viewExp((defender.getLevel()+1));
        
        ud = new Feed();
        ud.setCharacterName(defender.getCharactername());
        ud.setCharInv(wc.getCharactername());
        ud.setDateUpdated(CurrentDT.now());
        ud.setBattleId(this.getBattleId());
        
        if (defender.getCHP() <= 0)
           ud.setDescription(" has cursed you and got you killed.");
        else
           ud.setDescription(" has cursed you and you won!");
        
        ud.addFeed(ud);
        
        if (l.getExpPt() < (defender.getEPoint()+exp))
        {
            this.getMessageLog().add(defender.getCharactername()+" has Levelled Up to "+  (defender.getLevel()+1));
            
            defender.editCharInfo(defender.getCharactername(), "cLevel", "", 0, (defender.getLevel()+1));
            defender.editCharInfo(defender.getCharactername(), "sCountLeft", "", 0, (defender.getSCountLeft()+1));
            
            this.doLevel(statsD, defender, defender.getLevel());

            ud.setCharInv(defender.getCharactername());
            ud.setCharacterName(defender.getCharactername());
            ud.setDescription(" have levelled Up to "+  (defender.getLevel()+1));
            ud.setBattleId(0);
            ud.addFeed(ud);
            
            Comrade com = new Comrade();
            Vector<Comrade> vec = com.viewCComrades(defender.getCharactername());
            
            if (!vec.isEmpty())
            {
                ud.setDescription(" has levelled Up to "+  (defender.getLevel()+1));
                Iterator it = vec.iterator();
                Comrade friend = null;
                while(it.hasNext())
                {
                    friend = (Comrade)it.next();
                    ud.setCharacterName(friend.getFriendName());
                    ud.addFeed(ud);
                }
            }
        }
    }
    
    public Vector<String> getMessageLog() {
        return messageLog;
    }
    
    public void attackRoundMonsAttack(Monster attacker, Statistics statsAT, Statistics statsD, WispCharacter defender)
    {        
        for(int i=0;i<this.getNumAttacks(statsAT);i++) 
        {
            this.computeDamageM(attacker, statsAT, statsD, defender);            
            if(attacker.getCHP() < 0 || defender.getCHP() < 0 )
                break;
        }        
    }
    
    public void attackRoundCharAttack(WispCharacter attacker, Statistics statsAT, Statistics statsD, Monster defender, String type)
    {        
        for(int i=0;i<this.getNumAttacks(statsAT);i++) 
        {
            this.computeDamageC(attacker, statsAT, statsD, defender, type);            
            if (attacker.getCHP() < 0 || defender.getCHP() < 0 )
                break;
        }        
    }
    
    public boolean isDoAtk() {
        return doAtk;
    }

    public int getBattleId() {
        return battleId;
    }

    public void doLevel(Statistics wcs, WispCharacter wc, int lvl)
    {
        LevelUpClass lvlup = new LevelUpClass();
        lvlup.lvlUp(wcs, wc, lvl);
    }
    
    public double computeDamageC (WispCharacter attacker, Statistics statsAT, Statistics statsD, Monster defender, String type)
    {
        double damage = 0.0;
        boolean isCrit = false, isAccrt = false;
        isAccrt = this.getSuccessACC(attackAct(statsAT, statsD));
        
        if (isAccrt)
        {
            double rand = 0.0;
            int hp = defender.getCHP();
            isCrit = this.getSuccessCrit(critDamage(statsAT, statsD));
            
            if (type.equals("atk"))
            {
                rand = this.getRandom(getMIN(statsAT.getAtk()), statsAT.getAtk());
                
                if (isCrit)
                    damage = Math.ceil(rand  * 2);
                else
                    damage = Math.ceil(rand - statsD.getDef());
                if (damage < 0)
                    damage = 1;
                this.setDamage(attacker.getCharactername(), damage);
            }
            else if (type.equals("matk"))
            {
                rand = this.getRandom(getMIN(statsAT.getMAtk()), statsAT.getMAtk());
                
                if (isCrit)
                    damage = Math.ceil(rand  * 2);
                else
                    damage = Math.ceil(rand - (statsD.getRes() / 2));
                if (damage < 0)
                    damage = 1;
                this.setDamage(attacker.getCharactername(), damage);
            }
            
            Double d = new Double(damage);
            defender.setCHP(hp - d.intValue());
            defender.editHP(defender.getId(),defender.getCHP());
            if (!(this.getAction() == null))
            {//mana 
                System.out.print(attacker.getCharactername() + " attacked " + defender.getMName() + " and dealt "+d.toString()+" "+this.getAction());
                this.getMessages().add(attacker.getCharactername() + " attacked " + defender.getMName() + " and dealt "+d.toString()+" "+this.getAction());
                this.getMessageLog().add(attacker.getCharactername() + " attacked " + defender.getMName() + " and dealt "+d.toString()+" "+this.getAction());
                this.setAction(null);
            }
            else
            {
                System.out.print(attacker.getCharactername() + " attacked " + defender.getMName() + " and dealt "+d.toString()+" attack.");
                this.getMessages().add(attacker.getCharactername() + " attacked " + defender.getMName() + " and dealt "+d.toString()+" attack.");
                this.getMessageLog().add(attacker.getCharactername() + " attacked " + defender.getMName() + " and dealt "+d.toString()+" attack.");
            }
            if (isCrit)
            {   
                System.out.print(" critical hit!");
                this.getMessages().add(" CRITICAL HIT!!!");
                this.getMessageLog().add(" CRITICAL HIT!!!");
            }
        }
        else 
        {
            System.out.println(attacker.getCharactername() + " missed " + defender.getMName() + ".");
            this.getMessages().add(attacker.getCharactername() + " missed " + defender.getMName() + ".");
            this.getMessageLog().add(attacker.getCharactername() + " missed " + defender.getMName() + ".");
        }
        return damage;
    }
    
    public double computeDamageM (Monster attacker, Statistics statsAT, Statistics statsD, WispCharacter defender)
    {
        double damage = 0.0;
        boolean isCrit = false, isAccrt = false;
        isAccrt = this.getSuccessACC(attackAct(statsAT, statsD));
        
        if (isAccrt)
        {
            double rand = 0.0;
            int hp = defender.getCHP();
            isCrit = this.getSuccessCrit(critDamage(statsAT, statsD));
            
            rand = this.getRandom(getMIN(statsAT.getAtk()), statsAT.getAtk());
            
            if (isCrit)
                damage = Math.ceil(rand  * 2);
            else
                damage = Math.ceil(rand - statsD.getDef());
            if (damage < 0)
                    damage = 1;
            
            this.setDamage(this.getAr(), damage);
            
            Double d = new Double(damage);
            defender.setCHP(hp - d.intValue());
            defender.editCharInfo(defender.getCharactername(), "currentHP", "", 0.0, defender.getCHP());
            
            if (!(this.getAction() == null))
            {//mana 
                System.out.print(attacker.getMName() + " attacked " + defender.getCharactername() + " and dealt "+d.toString()+" "+this.getAction());
                this.getMessages().add(attacker.getMName() + " attacked " + defender.getCharactername() + " and dealt "+d.toString()+" "+this.getAction());
                this.getMessageLog().add(attacker.getMName() + " attacked " + defender.getCharactername() + " and dealt "+d.toString()+" "+this.getAction());
                this.setAction(null);
            }
            else
            {
                System.out.print(attacker.getMName() + " attacked " + defender.getCharactername() + " and dealt "+d.toString()+" attack.");
                this.getMessages().add(attacker.getMName() + " attacked " + defender.getCharactername() + " and dealt "+d.toString()+" attack.");
                this.getMessageLog().add(attacker.getMName() + " attacked " + defender.getCharactername() + " and dealt "+d.toString()+" attack.");
            }
            if (isCrit)
            {   
                System.out.print(" critical hit!");
                this.getMessages().add(" CRITICAL HIT!!!");
                this.getMessageLog().add(" CRITICAL HIT!!!");
            }
        }
        else 
        {
            System.out.println(attacker.getMName() + " missed " + defender.getCharactername() + ".");
            this.getMessages().add(attacker.getMName() + " missed " + defender.getCharactername() + ".");
            this.getMessageLog().add(attacker.getMName() + " missed " + defender.getCharactername() + ".");
        }
        return damage;
    }

    public void setBattleId(int battleId) {
        this.battleId = battleId;
    }
}
